/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package agent;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import messages.RegistrationReply;
import messages.RegistrationRequest;
import mobileipsimulation.AgentInterface;

/**
 *
 * @author Rente
 */
public class AgentReceiver extends Thread {

    static AgentInterface ai;
    private int portReceiver;
    private DatagramSocket socket;
    private String pacote, mensagem[];
    private Agent agente;

    public AgentReceiver(int portReceiver, Agent agente) {

        ai = agente.getAi();
       // ai.printMe("created"+agente.getFlag());
        this.agente = agente;
        this.portReceiver = portReceiver;
        //System.out.println("AgentReceiver  " + agente.getFlag() + "created with port "+this.portReceiver);


        this.agente = agente;
        this.portReceiver = portReceiver;
        System.out.println("AgentReceiver " + agente.getFlag() + "created with port " + this.portReceiver);


        this.start();
    }

    @Override
    public void run() {
        try {
            socket = new DatagramSocket(portReceiver);
            while (true) {
                byte[] buffer = new byte[5000];
                DatagramPacket request = new DatagramPacket(buffer, buffer.length);

                socket.receive(request);

                pacote = new String(request.getData(), 0, request.getLength());
                handleMensagem(pacote.split(";"));
            }
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
            return;
        } catch (SocketException ex) {
            ex.printStackTrace();
            System.out.println("UDP UNAVAILABLE");
            System.exit(0);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    private void handleMensagem(String[] mensagem) {
        
        ai.printMe("received " + agente.getFlag() + ":" + mensagem[0]);
        System.out.println("agente " + agente.getFlag() + " recebi qq coisa " + mensagem[0]);
        if (mensagem[0].equals("RegistrationRequest")) {
            System.out.println("step 0 " + mensagem[1] + " " + mensagem[6]);
            if (agente.getFlag().equals("foreign")) {
                System.out.println("step 1");
                if (!agente.containsVisitorEntry(mensagem[1])) {
                    System.out.println("step 2");
                    RegistrationRequest rr = new RegistrationRequest(true, mensagem[1], mensagem[2], mensagem[3], 49553 + "");
                    agente.sendMessage("localhost", rr.toString(), 49552);
                }
            } else if (agente.containsVisitorEntry(mensagem[1]) && mensagem[6].equals("true")) {
                System.out.println("Step X");
                agente.addMobilityBindingEntry(new MobilityBindingEntry(mensagem[1], mensagem[3], 1000));
                System.out.println("########## antes de remover tenho: " + agente.getVisitorEntries().size());
                agente.removeVisitorEntryByIP(mensagem[1]);
                System.out.println("########## depois de remover tenho: " + agente.getVisitorEntries().size());
                RegistrationReply rr = new RegistrationReply(mensagem[1], mensagem[2], mensagem[3], 49553 + "");
                agente.sendMessage("localhost", rr.toString(), 49553);
            } else if (!agente.containsVisitorEntry(mensagem[1]) && mensagem[6].equals("false")) {
                 System.out.println("Step Y");
                 agente.addVisitorEntry(new VisitorEntry(mensagem[1], mensagem[2], mensagem[3], 1000));
                if (agente.containsMobiltyBindingEntry(mensagem[1])) {
                    agente.removeMobilityBindingEntryByIP(mensagem[1]);
                }
                agente.sendMessage("localhost", "Confirmation;Sucesso;home", 2345);
            } else if (!agente.containsVisitorEntry(mensagem[1]) && mensagem[6].equals("true")) {
                System.out.println("Step Z");
                System.out.println("o foreing mandou-me registar este gajo: " + mensagem[1]);
                agente.addMobilityBindingEntry(new MobilityBindingEntry(mensagem[1], mensagem[3], 1000));
                RegistrationReply rr = new RegistrationReply(mensagem[1], mensagem[2], mensagem[3], 49553 + "");
                agente.sendMessage("localhost", rr.toString(), 49553);
            }
        } else if (mensagem[0].equals("RegistrationReply")) {
            if (agente.getFlag().equals("foreign")) {
                if (!agente.containsVisitorEntry(mensagem[1])) {
                    agente.addVisitorEntry(new VisitorEntry(mensagem[1], mensagem[2], mensagem[3], Integer.parseInt(mensagem[5])));
                    System.out.println("adicionei " + mensagem[1]);
                    agente.sendMessage(mensagem[1], "Confirmation;Sucesso;foreign", 2345);
                }
            }
        } else if (mensagem[0].equals("Packet")) {
            boolean isOut = true;
            if (agente.getFlag().equals("home")) {
                //ver se ele ta na rede
                if (!agente.getVisitorEntries().isEmpty()) {
                    for (VisitorEntry ve : agente.getVisitorEntries()) {
                        agente.sendMessage("localhost", pacote, 2345);
                        isOut = false;
                        ai.printMe("received msg for MN, he is at home");
                        System.out.println("***************** no movel em casa");
                        break;
                    }
                }
                //n esta na rede, vou reenviar para o foreign respectivo
                if (isOut) {
                    for (MobilityBindingEntry mbe : agente.getMobilityBindingEntries()) {
                        if (mbe.getHomeAddress().equals(mensagem[2])) {
                            agente.sendMessage("localhost", pacote, 49553);
                            ai.printMe("received msg for MN, he is not at home");
                            System.out.println("****************** no movel na rua");
                            break;
                        }
                    }
                }
            } // se for foreign
            else {
                System.out.println("sou foreign");
                for (VisitorEntry ve : agente.getVisitorEntries()) {
                    if (ve.getHomeAddress().equals(mensagem[2])) {
                        agente.sendMessage(ve.getHomeAddress(), pacote, 2345);
                        break;
                    }
                }
            }
        } else if (mensagem[0].equals("unregister")) {
            System.out.println("UNREGISTER " + mensagem[1]);
            agente.removeVisitorEntryByIP(mensagem[1]);
            agente.removeMobilityBindingEntryByIP(mensagem[1]);
        }
        //ai.printMe(mensagem.toString());
    }
}
